using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using System.Collections;
using System.Threading.Tasks;
using System.Threading;

namespace Mandelbrot_Florian.View
{
    public partial class MainForm : Form
    {

        #region Attribut

        private Controller.MainController _controller;
        private Pen _pen = new Pen(Color.Red, 2);
        private Rectangle _zoneSelection = new Rectangle();
        private bool _zooming = false;

        #endregion

        public MainForm(Controller.MainController controller)
        {
            InitializeComponent();
            _controller = controller;
        }
        private void MainForm_Load(object sender, EventArgs e)
        {
            List<string> listColorsName = Service.MandelbrotService.GetColorsName();
            foreach (string name in listColorsName)
                cbColors.Items.Add(name);
            initParam();
            _controller.UpdateLabels();
        }
        private void MainForm_FormClosed(object sender, FormClosedEventArgs e)
        {
            _controller.Dispose();
        }

        private void initParam()
        {
            _controller.CurrentModel = new Model.MandelbrotModel();
            _controller.CurrentModel.Img = new Bitmap(imgMandelbrot.Width, imgMandelbrot.Height);
            cbColors.SelectedItem = _controller.CurrentModel.ColorName;
        }

        #region Zoom

        private void imgMandelbrot_MouseDown(object sender, MouseEventArgs e)
        {
            _zoneSelection = new Rectangle();
            _zoneSelection.Location = e.Location;
            _zooming = true;
        }
        private void imgMandelbrot_MouseMove(object sender, MouseEventArgs e)
        {
            if (_zooming)
            {
                Model.MandelbrotModel model = _controller.CurrentModel;
                int w = e.X - _zoneSelection.Location.X;
                int h = e.Y - _zoneSelection.Location.Y;

                int border = Math.Min(w, h);
                _zoneSelection.Width = border;
                _zoneSelection.Height = border;

                //double ration = Math.Max(w / (double)model.Img.Width, h / (double)model.Img.Height);
                //_zoneSelection.Width = (int)(model.Img.Width * ration);
                //_zoneSelection.Height = (int)(model.Img.Height * ration);

                //_zoneSelection.Width = e.X - _zoneSelection.Location.X;
                //_zoneSelection.Height = e.Y - _zoneSelection.Location.Y;


                imgMandelbrot.Invalidate();

                //Model.MandelbrotModel zoomingModel = _controller.Service.Zoom(_zoneSelection);
                //_controller.UpdateLabels(zoomingModel);
            }

        }
        private void imgMandelbrot_MouseUp(object sender, MouseEventArgs e)
        {
            _zooming = false;
            imgMandelbrot.Invalidate();
            Model.MandelbrotModel zoomingModel = _controller.Service.Zoom(_zoneSelection);
            _controller.UpdateLabels(zoomingModel);
        }

        private void imgMandelbrot_Paint(object sender, PaintEventArgs e)
        {
            e.Graphics.DrawRectangle(_pen, _zoneSelection);
        }

        #endregion

        //private double intigralX, intigralY = 0.0;
        //private void updateRation()
        //{
        //    intigralX = (_Fx - _Sx) / imgMandelbrot.Width;
        //    intigralY = (_Fy - _Sy) / imgMandelbrot.Height;
        //}
        //private double GetXbyRation(long x)
        //{
        //    double X = _Sx + (x * intigralX);
        //    return X;
        //}
        //private double GetYbyRation(long y)
        //{
        //    double Y = _Sy + (y * intigralY);
        //    return Y;
        //}

        //private void DrawMandel()
        //{
        //    #region Local Attribut
        //    Bitmap b = new Bitmap(imgMandelbrot.Width, imgMandelbrot.Height);
        //    double x, y, x1, y1, xx, xmin, xmax, ymin, ymax = 0.0;
        //    int looper, s, z = 0;
        //    double intigralX, intigralY = 0.0;
        //    xmin = _Sx;
        //    ymin = _Sy;
        //    xmax = _Fx;
        //    ymax = _Fy;
        //    intigralX = (xmax - xmin) / imgMandelbrot.Width;//Interval between each X (each pixel)
        //    intigralY = (ymax - ymin) / imgMandelbrot.Height;//Interval between each Y (each pixel)
        //    x = xmin;
        //    #endregion

        //    Progressing(true);

        //    for (s = 1; s < imgMandelbrot.Width; s++)
        //    {
        //        y = ymin;
        //        for (z = 1; z < imgMandelbrot.Height; z++)
        //        {
        //            x1 = 0;
        //            y1 = 0;
        //            looper = 0;
        //            while (looper < _maxIteration && Math.Sqrt((x1 * x1) + (y1 * y1)) < 2)
        //            {
        //                looper++;
        //                xx = (x1 * x1) - (y1 * y1) + x;
        //                y1 = 2 * x1 * y1 + y;
        //                x1 = xx;
        //            }
        //            double perc = looper / (double)_maxIteration;
        //            int val = ((int)(perc * 255));
        //            b.SetPixel(s, z, _Colors[val]);
        //            y += intigralY;
        //        }
        //        x += intigralX;
        //        updateProgressBar();
        //    }

        //    Progressing(false);
        //    _bmp = b;
        //    imgMandelbrot.Image = _bmp;

        //}
        //private void DrawMandelByThread()
        //{
        //    #region Local Attribut
        //    Bitmap b = new Bitmap(imgMandelbrot.Width, imgMandelbrot.Height);
        //    double x, y, x1, y1, xx, xmin, xmax, ymin, ymax = 0.0;
        //    int looper, s, z = 0;
        //    double intigralX, intigralY = 0.0;
        //    xmin = _Sx;
        //    ymin = _Sy;
        //    xmax = _Fx;
        //    ymax = _Fy;
        //    intigralX = (xmax - xmin) / imgMandelbrot.Width;//Interval between each X (each pixel)
        //    intigralY = (ymax - ymin) / imgMandelbrot.Height;//Interval between each Y (each pixel)
        //    x = xmin;
        //    #endregion

        //    Progressing(true);

        //    for (s = 1; s < imgMandelbrot.Width; s++)
        //    {
        //        y = ymin;
        //        for (z = 1; z < imgMandelbrot.Height; z++)
        //        {
        //            x1 = 0;
        //            y1 = 0;
        //            looper = 0;
        //            while (looper < _maxIteration && Math.Sqrt((x1 * x1) + (y1 * y1)) < 2)
        //            {
        //                looper++;
        //                xx = (x1 * x1) - (y1 * y1) + x;
        //                y1 = 2 * x1 * y1 + y;
        //                x1 = xx;
        //            }
        //            double perc = looper / (double)_maxIteration;
        //            int val = ((int)(perc * 255));
        //            b.SetPixel(s, z, _Colors[val]);
        //            y += intigralY;
        //        }
        //        x += intigralX;
        //        updateProgressBar();
        //    }

        //    Progressing(false);
        //    _bmp = b;
        //    imgMandelbrot.Image = _bmp;
        //    _thread.Abort();
        //}
        //private void DrawMandelByTask()
        //{
        //    #region Local Attribut
        //    Bitmap b = new Bitmap(imgMandelbrot.Width, imgMandelbrot.Height);
        //    //double xmin, xmax, ymin, ymax = 0.0;
        //    //double intigralX, intigralY = 0.0;
        //    //xmin = _Sx;
        //    //ymin = _Sy;
        //    //xmax = _Fx;
        //    //ymax = _Fy;
        //    //intigralX = (xmax - xmin) / imgMandelbrot.Width;//Interval between each X (each pixel)
        //    //intigralY = (ymax - ymin) / imgMandelbrot.Height;//Interval between each Y (each pixel)

        //    #endregion

        //    Progressing(true);

        //    //// Use type parameter to make subtotal a long, not an int
        //    //Parallel.For<long>(0, nums.Length, () => 0, (j, loop, subtotal) =>
        //    //{
        //    //    subtotal += nums[j];
        //    //    return subtotal;
        //    //},
        //    //    (x) => Interlocked.Add(ref total, x)
        //    //);

        //    //double sum = 0.0;
        //    //double step = 1.0 / (double)num_steps;
        //    //object monitor = new object();
        //    //Parallel.For(0, num_steps, () => 0.0, (i, state, local) =>
        //    //{
        //    //    double x = (i + 0.5) * step;
        //    //    return local + 4.0 / (1.0 + x * x);
        //    //}, local => { lock (monitor) sum += local; });
        //    //return step * sum;

        //    //double x = xmin;
        //    //for (int s = 1; s < imgMandelbrot.Width; s++)
        //    //{
        //    Parallel.For(1, imgMandelbrot.Width, s =>
        //    {
        //        //double y = ymin;
        //        //for (int z = 1; z < imgMandelbrot.Height; z++)
        //        //{
        //        Parallel.For(1, imgMandelbrot.Height, z =>
        //        {
        //            double y = GetYbyRation(z);
        //            double x = GetXbyRation(s);
        //            double x1 = 0;
        //            double y1 = 0;
        //            int looper = 0;
        //            while (looper < _maxIteration && Math.Sqrt((x1 * x1) + (y1 * y1)) < 2)
        //            {
        //                looper++;
        //                double xx = (x1 * x1) - (y1 * y1) + x;
        //                y1 = 2 * x1 * y1 + y;
        //                x1 = xx;
        //            }
        //            double perc = looper / (double)_maxIteration;
        //            int val = ((int)(perc * 255));
        //            //Monitor.Enter(_locker);
        //            lock (_locker)
        //                b.SetPixel(s, z, _Colors[val]);
        //            //y += intigralY;
        //            //Monitor.Exit(_locker);
        //        }); // Parallel.For
        //        //x += intigralX;
        //        updateProgressBar();
        //    }); // Parallel.For

        //    Progressing(false);
        //    _bmp = b;
        //    imgMandelbrot.Image = _bmp;
        //}

        private void btnDraw_Click(object sender, EventArgs e)
        {
            _zoneSelection = new Rectangle();
            _controller.DrawMandel();
        }
        private void btnReset_Click(object sender, EventArgs e)
        {
            this.initParam();
            _controller.UpdateLabels();
            btnDraw.PerformClick();
        }
        private void btnSave_Click(object sender, EventArgs e)
        {
            if (saveFileDialog1.ShowDialog() == DialogResult.OK)
                _controller.SaveImgMandel(saveFileDialog1.FileName);
        }

    }
}